package cn.gov.sdcj.accountancy.entity

import groovy.transform.AutoClone

/**
 * <p>Description: 会计凭证对象</p>
 *
 * <li>id 为 凭证id(唯一)</li>
 * <li>inputDate 为 业务日期</li>
 * <li>year 为 会计年度</li>
 * <li>period 为 会计期间</li>
 * <li>groupName 为 凭证字</li>
 * <li>num 为 凭证号</li>
 * <li>attachments 为 附件数</li>
 * <li>preparerName 为 会计凭证的制单人</li>
 * <li>entries 为 凭证分录对象集合</li>
 * <p />
 *
 * Created by laijie on 2015/3/27.
 */
@AutoClone
class Voucher {
    int id;
    Date inputDate;
    int year;
    int period;
    String groupName;
    int num;
    int attachments;
    String preparerName;
    List<Entry> entries = new ArrayList<Entry>();
    void setId(int id) {
        this.id = id
        entries.each {
            it.setVoucherId(id)
        }
    }

    def add(Entry entry) {
        entries.add(entry)
        entries.sort { 0 - it.dc }
    }

    def add(Map attributes) {
        attributes.each { it -> this.setProperty(it.key as String, it.value) }
    }

    String toString() {
        String rst = "\n[凭证号:${groupName?:''}${num?:''}] [年度:${year?:''}] [期间:${period?:''}]"
        rst += "\n[业务日期:${inputDate?inputDate.format('yyyy-MM-dd'):''}] [附件数:${attachments?:''}]"
        entries.each { entry -> rst += "\n${entry}" }
        rst += "\n[制单人:${preparerName?:''}]"
        return rst
    }

    boolean equals(Object obj) {
        return (obj in Voucher
                && inputDate == obj.inputDate
                && year == obj.year
                && period == obj.period
                && groupName == obj.groupName
                && num == obj.num
                && attachments == obj.attachments
                && preparerName == obj.preparerName
        )
    }

    /**
     * 将 Voucher 对象中相同的 Entry 进行合并（金额相加）
     * @param voucher
     */
    private void mergeEntries(Voucher voucher) {
        List<Entry> newEntries = new ArrayList<Entry>()
        voucher.entries.each { entry ->
            def found = newEntries.find { it -> it == entry }
            if (found) {
                newEntries.remove(found)
                entry += found
            }
            newEntries.add(entry)
        }
        voucher.entries = newEntries
    }

    Voucher plus(Voucher other) {
        Voucher voucher = this.clone()
        if (equals(other)) {
            other.entries.each { entry ->
                voucher.add(entry)
            }
            mergeEntries(voucher)
        }

        return voucher
    }
}
